package org.common.utils.fasttest;

import org.apache.http.StatusLine;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * @author zhouzhibing
 * @date 2024/10/30
 */
public class TestVThread {
    /**
     * 平台线程数
     */
    static int PLATFORM_THREAD_COUNT;
    /**
     * 虚拟线程数
     */
    static int VIRTUAL_THREAD_COUNT;
    static CloseableHttpClient client;

    public static void main(String[] args) throws Exception {
        PLATFORM_THREAD_COUNT = 1;
        VIRTUAL_THREAD_COUNT = PLATFORM_THREAD_COUNT + 1;
        // 替换为这个即可解决死锁
        // VIRTUAL_THREAD_COUNT = PLATFORM_THREAD_COUNT;
        // 初始化apache http client
        client = initClient();
        // 设置虚拟线程池大小，最大线程数，最小可运行线程数 为平台线程数
        String strSize = Integer.toString(PLATFORM_THREAD_COUNT);
        System.setProperty("jdk.virtualThreadScheduler.parallelism", strSize);
        System.setProperty("jdk.virtualThreadScheduler.maxPoolSize", strSize);
        System.setProperty("jdk.virtualThreadScheduler.minRunnable", strSize);
        // 启动测试
        test();
    }

    public static void test() throws Exception {
        // 设置栅栏数为虚拟线程数
        CountDownLatch countDownLatch = new CountDownLatch(VIRTUAL_THREAD_COUNT);
        // 启动对应数量的虚拟线程任务
        for (int j = 0; j < VIRTUAL_THREAD_COUNT; j++) {
            Thread.ofVirtual().name("Virtual-" + j).start(() -> apachePoolingHttpClient(client, countDownLatch));
        }
        // 如果任务没有执行完毕，等待，会循环打印等待信息
        while (countDownLatch.getCount() != 0) {
            System.out.println("waiting " + countDownLatch.getCount());
            Thread.sleep(2000);
        }

//        Thread.sleep(20000);
        // 只有虚拟线程执行完毕，才会执行下面的代码
        System.out.println("end success");
    }

    /**
     * 初始化apache http client，没什么好看的
     *
     * @return
     */
    private static CloseableHttpClient initClient() {
        PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager();
        poolingConnManager.setMaxTotal(PLATFORM_THREAD_COUNT);
        return HttpClients.custom()
                .setConnectionManager(poolingConnManager)
                .build();
    }

    /**
     * apache http client 发送请求，关注点在最后一行代码，执行IO完毕，会调用countDownLatch.countDown()，表示当前虚拟线程执行完毕
     */
    private static void apachePoolingHttpClient(CloseableHttpClient client, CountDownLatch countDownLatch) {
        System.out.println("ThreadName " + Thread.currentThread().getName());
        HttpGet request = new HttpGet("https://www.baidu.com");
        try (CloseableHttpResponse execute = client.execute(request)) {
            StatusLine statusLine = execute.getStatusLine();
            System.out.println(statusLine.getStatusCode());
        } catch (Throwable e) {
            throw new RuntimeException(e);
        } finally {
            countDownLatch.countDown();
        }
    }


}
